<template>
  <div class="new-parnet" style="padding: 0 10px 0px; height: 100%; box-sizing: border-box">
    <el-card style="margin-bottom: 10px" class="box">
      <pre
        class="sqlExecutorEditor data-executor-editor"
        :style="$store.getters['global/getColor']"
        @contextmenu.prevent="onTagContexmenu"
      ></pre>
    </el-card>
  </div>
</template>
<script>
import sqlFormatter from "sql-formatter";

export default {
  name: "excute",
  mounted: function () {
    // this.loadDatasourceList();
    // 下面两行先后顺序不能改
    //
    // this.addEditorCompleter();
    // this.loadFavoriteList();
  },
  methods:{
    onTagContexmenu(event) {
      this.$contextmenu({
        items: [
          {
            label: "执行",
            icon: "editor-run",
            onClick: () => {
              let that = this.$parent;
              that.sqlExecutorEditor = that.initAceEditor(
                      "sqlExecutorEditor",
                      30
              );
              that.sqlExecutorEditor.setFontSize(
                      this.$store.getters["global/getFont"]
              );
              that.doExecutorSql();
            },
          },
          {
            label: "保存",
            icon: "editor-download",
            divided: true,
            minWidth: 0,
            children: [
              {
                label: "保存到便签",
                icon: "editor-cloud",
                onClick: () => {
                  this.$prompt("请输入名称", "提示", {
                    confirmButtonText: "确定",
                    cancelButtonText: "取消",
                    inputPattern: /^[\s\S]*.*[^\s][\s\S]*$/,
                    inputErrorMessage: "请输入非空的名称",
                  })
                          .then(({ value }) => {
                            this.$parent.sqlExecutorEditor = this.$refs.PageTableView.initAceEditor(
                                    "sqlExecutorEditor",
                                    30
                            );
                            if (
                                    this.$parent.sqlExecutorEditor.getValue().length <= 0
                            ) {
                              this.$message({
                                type: "error",
                                message: "收藏内容不能为空!",
                              });
                              return;
                            }
                            this.$emit("insertFavoriteList", value);
                          })
                          .catch((e) => {
                            console.log(e);
                            this.$message({
                              type: "info",
                              message: "取消输入",
                            });
                          });
                },
              },
              {
                label: "保存到本地",
                icon: "editor-local",
                onClick: () => {
                  try {
                    this.$parent.sqlExecutorEditor = this.$refs.PageTableView.initAceEditor(
                            "sqlExecutorEditor",
                            30
                    );
                    let sqlValue = this.$parent.sqlExecutorEditor.getSelectedText();
                    if (!sqlValue) {
                      sqlValue = this.$parent.sqlExecutorEditor.getValue();
                    }
                    this.openDownloadDialog(
                            new Blob([sqlValue], {
                              type: "text/plain",
                            }),
                            this.$route.query.name + ".sql"
                    );
                  } catch (e) {
                    this.$message({
                      type: "error",
                      message: e,
                    });
                  }
                },
              },
            ],
          },
          {
            label: "美化SQL",
            icon: "editor-format",
            activae: "true",
            onClick: () => {
              this.$parent.sqlExecutorEditor = this.$refs.PageTableView.initAceEditor(
                      "sqlExecutorEditor",
                      30
              );
              let dataSql = this.$parent.sqlExecutorEditor.getSelectedText();
              if (!!dataSql) {
                let range = this.$parent.sqlExecutorEditor.getSelectionRange();
                this.$parent.sqlExecutorEditor.remove(range);
              } else {
                dataSql = this.$parent.sqlExecutorEditor.getValue();
                this.$parent.sqlExecutorEditor.setValue("", 1);
              }
              if (!!dataSql) {
                dataSql = sqlFormatter.format(dataSql);
                this.$parent.sqlExecutorEditor.insert(dataSql);
              }
            },
          },
          {
            label: "字体大小",
            icon: "editor-font",
            divided: true,
            minWidth: 0,
            children: [
              {
                label: "小 10",
                icon:
                        "迷你 10".split(" ")[1] == "" + this.$parent.font_size
                                ? "editor-activate-label"
                                : "",
                onClick: () => {
                  this.$parent.font_size = 10;
                },
              },
              {
                label: "中 15",
                icon:
                        "迷你 15".split(" ")[1] == "" + this.$parent.font_size ||
                        this.$parent.font_size == 16
                                ? "editor-activate-label"
                                : "",
                onClick: () => {
                  this.$parent.font_size = 15;
                },
              },
              {
                label: "大 20",
                icon:
                        "迷你 20".split(" ")[1] == "" + this.$parent.font_size
                                ? "editor-activate-label"
                                : "",
                onClick: () => {
                  this.$parent.font_size = 20;
                },
              },
              {
                label: "超大 25",
                icon:
                        "迷你 25".split(" ")[1] == "" + this.$parent.font_size
                                ? "editor-activate-label"
                                : "",
                onClick: () => {
                  this.$parent.font_size = 25;
                },
              },
            ],
          },
          {
            label: "背景颜色",
            icon: "editor-backend",
            children: [
              {
                label: "Light(Vistual Studio)",
                icon:
                        this.$store.getters["global/getColor"] ==
                        "background-color: white; color: black"
                                ? "editor-activate-label"
                                : "",
                onClick: () => {
                  this.$store.commit(
                          "global/setColor",
                          "background-color: white; color: black"
                  );
                },
              },
              {
                label: "Solarized Light",
                icon:
                        this.$store.getters["global/getColor"] ==
                        "background-color: #F0FFF0; color: #333333"
                                ? "editor-activate-label"
                                : "",
                onClick: () => {
                  this.$store.commit(
                          "global/setColor",
                          "background-color: #F0FFF0; color: #333333"
                  );
                },
              },
              {
                label: "Dark+(default dark)",
                icon:
                        this.$store.getters["global/getColor"] ==
                        "background-color: #1e1e1e; color: #9CDCFE"
                                ? "editor-activate-label"
                                : "",
                onClick: () => {
                  this.$store.commit(
                          "global/setColor",
                          "background-color: #1e1e1e; color: #9CDCFE"
                  );
                },
              },
              {
                label: "Dark(Vistual Studio)",
                icon:
                        this.$store.getters["global/getColor"] ==
                        "background-color: #1e1e1e; color: #DCDCAA"
                                ? "editor-activate-label"
                                : "",
                onClick: () => {
                  this.$store.commit(
                          "global/setColor",
                          "background-color: #1e1e1e; color: #DCDCAA"
                  );
                },
              },
              {
                label: "One Dark Pro",
                icon:
                        this.$store.getters["global/getColor"] ==
                        "background-color: #282C34; color: #98C379"
                                ? "editor-activate-label"
                                : "",
                onClick: () => {
                  this.$store.commit(
                          "global/setColor",
                          "background-color: #282C34; color: #98C379"
                  );
                },
              },
            ],
          },
        ],
        event,
        //x: event.clientX,
        //y: event.clientY,
        zIndex: 3,
        minWidth: 230,
      });
      return false;
    },
  },
  getExecuteSql() {
    if (this.$route.query.dbType == "com.mysql.jdbc.Driver") {
      return (
              "select * from " +
              "`" +
              this.$route.query.dbName +
              "`" +
              "." +
              "`" +
              this.$route.query.tableName +
              "`" +
              " limit " +
              this.pagesize +
              " offset " +
              (this.currentPage - 1) * this.pagesize +
              ";"
      );
    } else if (this.$route.query.dbType == "org.postgresql.Driver") {
      return (
              "select * from " +
              this.$route.query.dbName +
              "." +
              this.$route.query.tableName +
              " limit " +
              this.pagesize +
              " offset " +
              (this.currentPage - 1) * this.pagesize +
              ";"
      );
    } else if (
            this.$route.query.dbType == "net.sourceforge.jtds.jdbc.Driver"
    ) {
      return (
              "select top " +
              this.pagesize +
              " * from " +
              this.$route.query.dbName +
              "." +
              this.$route.query.tableName
      );
    }

    return (
            "select * from " +
            this.$route.query.dbName +
            "." +
            this.$route.query.tableName +
            " limit " +
            this.pagesize +
            " offset " +
            (this.currentPage - 1) * this.pagesize +
            ";"
    );
  },
  loadEditorData(choiceDatasourceId) {
    datasourceApi
            .getEditorData({ sourceId: choiceDatasourceId })
            .then((json) => {
              let data = json.data || {};
              this.editorDbInfo = data.db || [];
              this.editorDbTableInfo = data.table || {};
              this.editorColumnInfo = data.column || {};
            });
  },
  async addEditorCompleter() {
    let that = this;
    var languageTools = ace.require("ace/ext/language_tools");
    languageTools.addCompleter({
      needDestory: true, // 一定得加上这个参数~不然页面生命周期内页面的切换，编辑器会有多个相同的completer
      getCompletions: function (editor, session, pos, prefix, callback) {
        var isFound = false;
        var callbackArr = [];
        var lineStr = session.getLine(pos.row).substring(0, pos.column - 1);
        var currentStr = session.getLine(pos.row).substring(0, pos.column);
        console.log(lineStr);
        if (lineStr.endsWith("from ") || lineStr.endsWith("join ")) {
          // 库
          for (var i = 0; i < that.editorDbInfo.length; i++) {
            callbackArr.push({
              caption: that.editorDbInfo[i].dbName,
              snippet: that.editorDbInfo[i].dbName,
              meta: "database",
              type: "snippet",
              score: 1000,
            });
          }
          // 所有表
          for (var key in that.editorDbTableInfo) {
            var tableInfo = that.editorDbTableInfo[key];
            for (var i = 0; i < tableInfo.length; i++) {
              var caption = !!tableInfo[i].tableComment
                      ? tableInfo[i].tableName + "-" + tableInfo[i].tableComment
                      : tableInfo[i].tableName;
              callbackArr.push({
                caption: caption,
                snippet: tableInfo[i].tableName,
                meta: "table",
                type: "snippet",
                score: 1000,
              });
            }
          }
          callback(null, callbackArr);
        } else if (currentStr.endsWith(".")) {
          // 获取当前用户输入的SQL
          var sqlValue = "";
          // 往前加
          for (var i = pos.row; i >= 0; i--) {
            var tempLine = session.getLine(i);
            sqlValue = tempLine + " " + sqlValue;
            if (tempLine.indexOf(";") >= 0) {
              break;
            }
          }
          // 往后加
          for (var i = pos.row + 1; i < session.getLength(); i++) {
            var tempLine = session.getLine(i);
            sqlValue = sqlValue + " " + tempLine;
            if (tempLine.indexOf(";") >= 0) {
              break;
            }
          }
          var reg = /("([^\\\"]*(\\.)?)*")|('([^\\\']*(\\.)?)*')|(-{2,}.*?(\r|\n))|(\/{2,}.*?(\r|\n))|(\/\*(\n|.)*?\*\/)/g;

          sqlValue = sqlValue.replace(reg, function (word) {
            // 去除注释后的文本
            return /^\/{2,}/.test(word) || /^\/\*/.test(word) ? "" : word;
          });

          // 由于后端无法解析别名+.，所以要把当前输入的sql中的.去掉
          sqlValue = sqlValue.replace(currentStr, lineStr);
          let response = datasourceApi
                  .tableAlias({
                    sql: sqlValue,
                    driverType: that.$parent.$parent.$parent.$parent.dbType,
                  })
                  .then((response) => {
                    let splitStr = currentStr.split(",");
                    splitStr = splitStr[splitStr.length - 1];
                    splitStr = splitStr.split(" ");
                    splitStr = splitStr[splitStr.length - 1];
                    let aliasName = splitStr
                            .substring(0, splitStr.length - 1)
                            .trim();
                    // 如果别名匹配到了真实表分两种情况
                    // 1、这个是别名.
                    // 2、这个是from 后面数据库后面按.
                    if (response.data && response.data[aliasName]) {
                      let splitStr = response.data[aliasName].split(".");
                      if (splitStr.length > 1) {
                        let dbName = splitStr[0].trim();
                        let tableName = splitStr[1].trim();
                        // mysql和postgresql的查询不一样
                        let editorColumnInfo;
                        if (
                                that.$parent.$parent.$parent.$parent.dbType ===
                                "com.mysql.jdbc.Driver"
                        ) {
                          editorColumnInfo = that.editorColumnInfo[tableName];
                        } else {
                          editorColumnInfo = that.editorColumnInfo[dbName];
                        }

                        for (var i = 0; i < editorColumnInfo.length; i++) {
                          if (editorColumnInfo[i].tableName !== tableName) {
                            continue;
                          }
                          callbackArr.push({
                            caption: editorColumnInfo[i].name,
                            snippet: editorColumnInfo[i].name,
                            meta: "column",
                            type: "snippet",
                            score: 1000,
                          });
                        }
                      } else {
                        let tableName = splitStr[0].trim();
                        let editorColumnInfo = that.editorColumnInfo[tableName];
                        for (var i = 0; i < editorColumnInfo.length; i++) {
                          callbackArr.push({
                            caption: editorColumnInfo[i].name,
                            snippet: editorColumnInfo[i].name,
                            meta: "column",
                            type: "snippet",
                            score: 1000,
                          });
                        }
                      }
                    } // 处理数据库按点的情况
                    else {
                      // 所有表
                      var tableInfo = that.editorDbTableInfo[aliasName];
                      for (var i = 0; i < tableInfo.length; i++) {
                        var caption = !!tableInfo[i].tableComment
                                ? tableInfo[i].tableName + "-" + tableInfo[i].tableComment
                                : tableInfo[i].tableName;
                        callbackArr.push({
                          caption: caption,
                          snippet: tableInfo[i].tableName,
                          meta: "table",
                          type: "snippet",
                          score: 1000,
                        });
                      }
                    }
                    callback(null, callbackArr);
                    return;
                  });
        } else if (
                lineStr.endsWith("select ") ||
                lineStr.endsWith("where ") ||
                lineStr.endsWith("and ")
        ) {
          var queryText = "";
          // 往前加
          for (var i = pos.row; i >= 0; i--) {
            var tempLine = session.getLine(i);
            queryText = tempLine + " " + queryText;
            if (tempLine.indexOf(";") >= 0) {
              break;
            }
          }
          // 往后加
          for (var i = pos.row + 1; i < session.getLength(); i++) {
            var tempLine = session.getLine(i);
            queryText = queryText + " " + tempLine;
            if (tempLine.indexOf(";") >= 0) {
              break;
            }
          }
          // 所有表，找下面的字段列表
          for (var key in that.editorDbTableInfo) {
            var tableInfo = that.editorDbTableInfo[key];
            for (var i = 0; i < tableInfo.length; i++) {
              if (queryText.indexOf(tableInfo[i].tableName) < 0) {
                continue;
              }
              var columnInfo;
              if (
                      that.$parent.$parent.$parent.$parent.dbType ===
                      "com.mysql.jdbc.Driver"
              ) {
                columnInfo = that.editorColumnInfo[tableInfo[i].tableName];
                if (!!columnInfo) {
                  for (var j = 0; j < columnInfo.length; j++) {
                    var caption = !!columnInfo[j].description
                            ? columnInfo[j].name + "-" + columnInfo[j].description
                            : columnInfo[j].name;
                    callbackArr.push({
                      caption: caption,
                      snippet: columnInfo[j].name,
                      meta: "column",
                      type: "snippet",
                      score: 1000,
                    });
                  }
                  isFound = true;
                }
              } else {
                columnInfo = that.editorColumnInfo[key];
                if (!!columnInfo) {
                  for (var j = 0; j < columnInfo.length; j++) {
                    if (columnInfo[j].tableName !== tableInfo[i].tableName) {
                      continue;
                    }
                    var caption = !!columnInfo[j].description
                            ? columnInfo[j].name + "-" + columnInfo[j].description
                            : columnInfo[j].name;
                    callbackArr.push({
                      caption: caption,
                      snippet: columnInfo[j].name,
                      meta: "column",
                      type: "snippet",
                      score: 1000,
                    });
                  }
                  isFound = true;
                }
              }
            }
          }
          callback(null, callbackArr);
        } else {
          // 库
          for (var i = 0; i < that.editorDbInfo.length; i++) {
            callbackArr.push({
              caption: that.editorDbInfo[i].dbName,
              snippet: that.editorDbInfo[i].dbName,
              meta: "database",
              type: "snippet",
              score: 1000,
            });
          }
          // 所有表
          for (var key in that.editorDbTableInfo) {
            var tableInfo = that.editorDbTableInfo[key];
            for (var i = 0; i < tableInfo.length; i++) {
              var caption = !!tableInfo[i].tableComment
                      ? tableInfo[i].tableName + "-" + tableInfo[i].tableComment
                      : tableInfo[i].tableName;
              callbackArr.push({
                caption: caption,
                snippet: tableInfo[i].tableName,
                meta: "table",
                type: "snippet",
                score: 1000,
              });
              var columnInfo = that.editorColumnInfo[tableInfo[i].tableName];
              if (columnInfo) {
                for (var j = 0; j < columnInfo.length; j++) {
                  var caption = !!columnInfo[j].description
                          ? columnInfo[j].name + "-" + columnInfo[j].description
                          : columnInfo[j].name;
                  callbackArr.push({
                    caption: caption,
                    snippet: columnInfo[j].name,
                    meta: "column",
                    type: "snippet",
                    score: 1000,
                  });
                }
              }
            }
          }
          callback(null, callbackArr);
        }
      },
    });
  },
  initLoadDataList(param) {
    this.$emit("initLoadDataList", param);
  },
  loadDatasourceList() {
    this.$emit("loadDatasourceList");
  },
};
</script>
<style>
  .ace-monokai .ace_indent-guide {
   background-image:none!important;
}
</style>
